home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 / Ham Radio 2000.iso / ham2000 / misc / qsocord / qso23.asm < prev    next >
Assembly Source File  |  1993-10-17  |  23KB  |  721 lines

  1. ;---------------------------------------------------
  2. ;
  3. ;                    QSOxx.ASM
  4. ;
  5. ;                    QSOcorder
  6. ;
  7. ;        Digital Audio "Instant Replay" Unit
  8. ;
  9. ;
  10. ;           Dr. Steven E. Reyer, WA9VNJ
  11. ;
  12. ;                Reyer & Associates
  13. ;                  P.O. Box 17821
  14. ;               Milwaukee, WI  53217
  15. ;                       USA
  16. ;
  17. ;---------------------------------------------------
  18. ;      For personal, noncommercial use only.
  19. ;---------------------------------------------------
  20. ;
  21. ; NOTE:  version number and date appear on
  22. ;        ROM page 3, and on the top of the
  23. ;        following lines.
  24. ;
  25. ; v. 2.3 - 10/17/93 - include NOPs for JNT1 on pwr-up
  26. ; v. 2.2 - 09/29/93 - remove unnecessary subroutines
  27. ; v. 2.1 - 08/10/93 - change manual reboot method
  28. ; v. 2.0 - 08/09/93 - add manual record mode
  29. ; v. 1.2 - 08/07/93 - include clear RAM routine
  30. ; v. 1.1 - 08/07/93 - shorten record loop to 42/55
  31. ; v. 1.0 - 08/06/93 - original program
  32. ;
  33. ;---------------------------------------------------
  34. ;
  35. ; This program runs on an Intel 8748H (high speed version)
  36. ; microcontroller to allow "Instant Replay" of received
  37. ; communications quality audio.  It requires two 62256
  38. ; RAMs (32K x 8), an Analog Devices AD7569 8-bit audio
  39. ; I/O port, a 74LS374/574 demultiplexing latch, and 
  40. ; analog antialiasing and reconstruction lowpass filters,
  41. ; and speaker driver amplifier, such as an LM380.
  42. ;
  43. ; The crystal required is 11 MHz (or 11.0592 MHz, which
  44. ; exceeds the specification of the 8748H, but not by very
  45. ; much, and should work fine in most instances).
  46. ;
  47. ; Three switches to control the system are connected as
  48. ; follows:
  49. ;         T0 (pin 1) - 10 second repeat pushbutton
  50. ;         T1 (pin 39)- 5 second repeat pushbutton
  51. ;        INT (pin 6) - Sample rate selector
  52. ;                      (open   = 13.41 kHz)
  53. ;                      (ground = 17.55 kHz)
  54. ;
  55. ; The sample rate determines the quality of the replayed
  56. ; audio, as well as the duration.  At the slow rate, the
  57. ; "10 second" switch plays for 9.8 seconds, and the
  58. ; "5 second" switch plays for 4.9 seconds.  At the fast
  59. ; rate, the times are 7.5 and 3.7 seconds.  At the slow
  60. ; rate, there will be some reconstruction noise, since
  61. ; the storage algorithm uses a /2 decimation, and a 
  62. ; corresponding x2 interpolation, with simple 2-point
  63. ; averaging digital filtering.  With the 3 kHz, 3rd order
  64. ; Chebyshev lowpass filters, this causes images from the
  65. ; sampling/decimation to be heard.  A 3 kHz input signal
  66. ; will image to a resulting -30 dB at the fast rate, and
  67. ; -10 dB at the slow rate.  Thus, the trade-off is between
  68. ; better quality vs. longer record time.  Fortunately,
  69. ; ham radio applications will involve signals with little
  70. ; high frequency power.
  71. ;
  72. ; There are 42 states between samples at the fast rate,
  73. ; and 55 states at the slow rate.  With the 11.0592 MHz
  74. ; clock, each state takes about 1.356 microseconds,
  75. ; = (15/11.0592) microseconds.
  76. ;
  77. ; The RAM address is multiplexed onto Port 1, and 
  78. ; demultiplexed with the 74LS374 latch.  The latch
  79. ; holds the MS bits, and Port 1 holds the LS bits.
  80. ; The MS bit of the latch operates the overload LED.
  81. ; Data transfers are made on the "BUS."  Port 2 is used
  82. ; to construct the control signals as follows:
  83. ;
  84. ;  Port bit   Pin      Signal
  85. ;    P27      38     CS1- to RAM 1
  86. ;    P26      37     CS0- to RAM 0
  87. ;    P25      36     WE-  to RAMs
  88. ;    P24      35     OE-  to RAMs
  89. ;    P23      24     WR-  to AD7569
  90. ;    P22      23     ST-  to AD7569
  91. ;    P21      22     RD-  to AD7569
  92. ;    P20      21     LATCH- to 74LS374
  93. ;
  94. ;Note:  ST- starts the A/D converter on the falling edge.
  95. ;       It is a normally-low signal.
  96. ;
  97. ; Registers used are as follows:
  98. ;
  99. ;   R7 - MS start address in buffer/temp constant 0
  100. ;   R6 - LS start address in buffer
  101. ;   R5 - MS end address
  102. ;   R4 - Temporary sample storage
  103. ;   R3 - Temporary sample storage
  104. ;   R2 - MS current address pointer
  105. ;   R1 - LS current address pointer
  106. ;   R0 - sample average
  107. ;
  108. ;There are two modes of operation in the QSOcorder:
  109. ;
  110. ; AUTOMATIC MODE:
  111. ; ---------------
  112. ; When a "play" is requested, R7/R6 hold the computed
  113. ; starting "play address."  This is either 5 seconds
  114. ; or 10 seconds earlier than the present buffer address.
  115. ; R5 is used to hold the MS end address, so the "play"
  116. ; knows when to stop and return to the "start" address
  117. ; to continue playing.  R2/R1 are used as a temporary
  118. ; address during playing.  When playing is no longer
  119. ; requested, R5/R6 are put into R2/R1 to continue 
  120. ; recording.  This will cause recording to begin at the
  121. ; same place it was halted when the play request was made.
  122. ; Playing continues as long as a play button is pressed.
  123. ;
  124. ; An "Overload LED" is connected to the latch MSB and is 
  125. ; used to set the receiver audio gain.  Adjust the
  126. ; receiver audio until the LED just flickers, and then
  127. ; back-off the setting a small amount.  Too much receiver
  128. ; audio will cause some distortion, and too little will
  129. ; allow quantizing noise to be heard.
  130. ;
  131. ;
  132. ; MANUAL MODE:
  133. ; ------------
  134. ; Manual mode is entered by holding the 10-second push-
  135. ; button down while powering-up the system.  It will then
  136. ; enter the 1 second memory clear routine, and finally
  137. ; enter manual mode and light up the LED.  This indicates
  138. ; it is idling, and ready for a record command.  The record
  139. ; command consists of a quick press of the 10 second button.
  140. ; The LED will extinguish, and a 10 second recording will
  141. ; be made, after which the system lights up the LED and
  142. ; awaits a play command.  This is similarly caused by a quick
  143. ; press of the 10 second button.  It will play the complete
  144. ; 10 seconds, and return to the play-idle state, awaiting
  145. ; another play command.  Whenever the LED is on, in either
  146. ; idle state, the mode may be cancelled by a quick press
  147. ; of the 5 second button.  The system will then enter the
  148. ; automatic mode immediately.  The manual mode can only
  149. ; be reentered by the power-up technique described above.
  150. ;
  151. ; The playback sample rate in manual mode will vary
  152. ; depending on whether the 10 second button is being
  153. ; pressed.  This will also happen during record mode.
  154. ; The variation is from 17.55 kHz to 16.75 kHz which
  155. ; causes a noticible change on music but is barely
  156. ; detectable on voice.
  157. ;
  158. ; There is a 1 second delay (with LED on) upon power-up
  159. ; in either mode, for the RAM-clear routine.
  160. ;
  161. ;--------------------------------------------------------
  162. ;------------------- Memory Page 0 ----------------------
  163. ;--------------------------------------------------------
  164.     ORG    0000H        ;Start of EPROM memory
  165.  
  166. START    DIS    I        ;Turn off external interrupt
  167.     DIS    TCNTI        ;...and timer counter int
  168.     CALL    INIT        ;Initialize ports and data
  169.     JNT0    MANA        ;Manual record mode request
  170.     NOP            ;Room for JNT1 on power up
  171.     NOP            ;Same
  172.     CALL    CLEAR        ;Clear all of RAM memory
  173.  
  174. ;----------------- Using RAM chip 0 ---------------------
  175. ;--------------------- RECORD ---------------------------
  176. ;Reset the start address to previous end address
  177. REC0X    JF1    PLAY0A        ;If manual, keep playing
  178. RECMAN    MOV    A,R5        ;Get MS end addr byte
  179.     MOV    R2,A        ;Put into counter
  180.     MOV    A,R6        ;Get LS end addr byte
  181.     MOV    R1,A        ;Put into counter
  182.     MOV    R7,#0        ;Constant zero
  183.  
  184. ;Start the A/D converter                           states
  185. REC0    ORL    P2,#00000100B    ;ST- = 1              2
  186.     ANL    P2,#11111011B    ;ST- = 0              2 A/D
  187.     JNI    FAST0A        ;Fast sampling?       2
  188.     CALL    WAIT13        ;No, add 13 states  (13)
  189.  
  190. ;Read the A/D converter into accum
  191. FAST0A    MOVX    A,@R1        ;Dummy to reset BUS   2
  192.     ANL    P2,#11111101B    ;RD- = 0              2
  193.     INS    A,BUS        ;Read A/D on BUS      2
  194.     ORL    P2,#00000010B    ;RD- = 1              2
  195.  
  196. ;Send accum data to D/A converter
  197.     OUTL    BUS,A        ;Send data to BUS     2
  198.     ANL    P2,#10110110B    ;WR-,LATCH-,CS0-=0    2
  199.     ORL    P2,#00001000B    ;WR- = 1              2 D/A
  200.     MOV    R4,A        ;Save sample          1
  201.  
  202. ;Check whether overload is occurring.  F0=1=yes.
  203.     MOV    A,R2        ;MS byte addr         1
  204.     ANL    A,#01111111B    ;Turn LED on          2
  205.     JF0    ON0A        ;Should be on?          2
  206.     ORL    A,#10000000B    ;No, turn off          2
  207.     JMP    OFF0A        ;Continue          2
  208. ON0A    NOP            ;Pad timing         (1)
  209.     NOP            ;             (1)
  210.     NOP            ;             (1)
  211.     NOP            ;             (1)
  212.  
  213. ;Put sample average into RAM at current address
  214. ;Send address to latches
  215. OFF0A    OUTL    P1,A        ;Out to port 1        2
  216.     ORL    P2,#00000001B    ;LATCH- = 1           2
  217.     MOV    A,R1        ;LS byte addr         1
  218.     OUTL    P1,A        ;Out to port 1        2
  219.  
  220. ;Send data to RAM
  221.     MOV    A,R0        ;Get sample average   1
  222.     OUTL    BUS,A        ;Put onto BUS         2
  223.     ANL    P2,#11011111B    ;WE- = 0              2
  224.     ORL    P2,#00100100B    ;WE-=1, ST-=1         2
  225.  
  226. ;Start the A/D converter
  227.     ANL    P2,#11111011B    ;ST- = 0              2 A/D
  228.     JNI    FAST0B        ;Fast sampling?       2
  229.     CALL    WAIT13        ;No, add 13 states  (13)
  230.  
  231. ;Read the A/D converter into accum
  232. FAST0B    MOVX    A,@R1        ;Dummy to reset BUS   2
  233.     ANL    P2,#11111101B    ;RD- = 0              2
  234.     INS    A,BUS        ;Read A/D data on BUS 2
  235.     ORL    P2,#01000010B    ;RD-=1;CS0-=1         2
  236.  
  237. ;Send accum data to D/A converter
  238.     OUTL    BUS,A        ;Send data to BUS     2
  239.     ANL    P2,#11110111B    ;WR- = 0              2
  240.     ORL    P2,#00001000B    ;WR- = 1              2 D/A
  241.  
  242. ;Check for overload - set F0 if yes.
  243.     CLR    F0        ;LED flag off          1
  244.     JNZ    OFF0B        ;Overload?          2
  245.     CPL    F0        ;Yes!  Turn on         (1)
  246.     JMP    ON0B        ;Continue         (2)
  247. OFF0B    NOP            ;Pad timing          1
  248.     NOP            ;              1
  249.     NOP            ;              1
  250.  
  251. ;Find the average
  252. ON0B    ADD    A,R4        ;Add old sample       1
  253.     RRC    A        ;Average the two      1
  254.     MOV    R0,A        ;Save for later       1
  255.  
  256. ;Increment address counters in R2:R1
  257.     MOV    A,R1        ;Get LS byte          1
  258.     ADD    A,#1        ;Bump LS byte         2
  259.     MOV    R1,A        ;Replace              1
  260.     MOV    A,R2        ;Get MS byte          1
  261.     ADDC    A,R7        ;Add carry + (R7=0)   1
  262.     MOV    R2,A        ;Replace              1
  263.     JB7    TEST1A        ;Change RAM?          2
  264.  
  265. TEST0    JT1    TA        ;T1 up?  Check T0     2
  266.     MOV    A,R2        ;No, fix start addr
  267.     XRL    A,#10000000B    ;Addr 5 secs back
  268.     MOV    R7,A        ;Save as MS start
  269.     JMP    PL0        ;Now play
  270.  
  271. TA    JT0    REC0        ;T0 up?  Keep rec.    2
  272.     JF1    REC0        ;Manual, ignore T0
  273.  
  274.     MOV    A,R2        ;Addr 10 secs back
  275.     MOV    R7,A        ;Save as MS start
  276.  
  277. PL0    MOV    A,R1        ;LS byte addr
  278.     MOV    R6,A        ;Save LS start/end
  279.     MOV    A,R2        ;Get MS addr end
  280.     MOV    R5,A        ;Save as MS end
  281.  
  282. ;Set starting address for playing
  283. START0    MOV    A,R7        ;Get MS start
  284.     MOV    R2,A        ;Into counter
  285.     MOV    A,R6        ;Get LS start
  286.     MOV    R1,A        ;Into counter
  287.  
  288. ;------------------- PLAY --------------------------
  289. ;Get a byte from current address into accum
  290. ;Send address to latches
  291. PLAY0    MOVX    A,@R1        ;Dummy to reset BUS   2
  292.     ANL    P2,#10111111B    ;CS0- = 0             2
  293.     MOV    A,R2        ;MS byte addr         1
  294.     ORL    A,#10000000B    ;Turn off LED          2
  295.     OUTL    P1,A        ;Out to port 1        2
  296.     ANL    P2,#11111110B    ;LATCH- = 0           2
  297.     ORL    P2,#00000001B    ;LATCH- = 1           2
  298.     MOV    A,R1        ;LS byte addr         1
  299.     OUTL    P1,A        ;Out to port 1        2
  300.     ANL    P2,#11101111B    ;OE- = 0              2
  301.     INS    A,BUS        ;Read RAM data on BUS 2
  302.     ORL    P2,#00010000B    ;OE- = 1              2
  303.     ORL    P2,#01000000B    ;CS0- = 1             2
  304.  
  305. ;Find the average
  306.     MOV    R3,A        ;Save sample for now  1
  307.     ADD    A,R4        ;R4 = old sample      1
  308.     RRC    A        ;Find average         1
  309.     NOP            ;Pad timing          1
  310.     NOP            ;              1
  311.     NOP            ;              1
  312.     NOP            ;              1
  313.     NOP            ;              1
  314.  
  315. ;Send accum data to D/A converter
  316.     JNI    FAST0C        ;Fast sampling?       2
  317.     CALL    WAIT13        ;No, add 13 states  (13)
  318. FAST0C    OUTL    BUS,A        ;Send data to BUS     2
  319.     ANL    P2,#11110111B    ;WR- = 0              2
  320.     ORL    P2,#00001000B    ;WR- = 1              2 D/A
  321.  
  322. ;Increment address counters in R2:R1
  323.     MOV    A,R1        ;Get LS byte          1
  324.     ADD    A,#1        ;Bump LS byte         2
  325.     MOV    R1,A        ;Replace              1
  326.     MOV    A,R2        ;Get MS byte          1
  327.     ADDC    A,#0        ;Add carry            2
  328.     MOV    R2,A        ;Replace              1
  329.     JB7    TST1A        ;Change RAM?          2
  330.  
  331.     MOV    A,R1        ;Get LS addr          1
  332.     XRL    A,R6        ;At end?              1
  333.     JNZ    TST0        ;Not yet              2
  334.  
  335.     MOV    A,R2        ;Get MS addr
  336.     XRL    A,R5        ;At end?
  337.     JZ    START0        ;Yes, restart
  338.  
  339. TST0    JT1    TB        ;T1 up?               2
  340.     JMP    PLAY0A        ;No, play sound       2
  341.  
  342. TB    JT0    REC0X        ;Finished playing?
  343.  
  344. PLAY0A    MOV    A,R3        ;Recall new sample    1
  345.     MOV    R4,A        ;Make into old        1
  346.     CALL    WAIT13        ;Wait 13 states         13
  347.     NOP            ;Pad timing          1
  348.  
  349. ;Send sample to D/A converter
  350.     JNI    FAST0D        ;Fast sampling?       2
  351.     CALL    WAIT13        ;No, add 13 states  (13)
  352. FAST0D    OUTL    BUS,A        ;Send data to BUS     2
  353.     ANL    P2,#11110111B    ;WR- = 0              2
  354.     ORL    P2,#00001000B    ;WR- = 1              2 D/A
  355.     JMP    PLAY0        ;Keep playing         2
  356.  
  357. TEST1A    JMP    TEST1        ;Cross page jumps
  358. TST1A    JMP    TST1
  359. MANA    JMP    MANUAL
  360.  
  361. ;--------------------------------------------------------
  362. ;------------------- Memory Page 1 ----------------------
  363. ;--------------------------------------------------------
  364.     ORG    0100H
  365.  
  366. ;----------------- Using RAM chip 1 ---------------------
  367. ;--------------------- RECORD ---------------------------
  368. ;Reset the start address to previous end address
  369. REC1X    JF1    PLAY1A        ;If manual, keep playing
  370.     MOV    A,R5        ;Get MS end addr byte
  371.     MOV    R2,A        ;Put into counter
  372.     MOV    A,R6        ;Get LS end addr byte
  373.     MOV    R1,A        ;Put into counter
  374.     MOV    R7,#0        ;Constant zero
  375.  
  376. ;Start the A/D converter
  377. REC1    ORL    P2,#00000100B    ;ST- = 1              2
  378.     ANL    P2,#11111011B    ;ST- = 0              2 A/D
  379.     JNI    FAST1A        ;Fast sampling?       2
  380.     CALL    WAIT13        ;No, add 13 states  (13)
  381.  
  382. ;Read the A/D converter into accum
  383. FAST1A    MOVX    A,@R1        ;Dummy to reset BUS   2
  384.     ANL    P2,#11111101B    ;RD- = 0              2
  385.     INS    A,BUS        ;Read A/D data on BUS 2
  386.     ORL    P2,#00000010B    ;RD- = 1              2
  387.  
  388. ;Send accum data to D/A converter
  389.     OUTL    BUS,A        ;Send data to BUS     2 
  390.     ANL    P2,#01110110B    ;WR-,LATCH-,CS1-=0    2
  391.     ORL    P2,#00001000B    ;WR- = 1              2 D/A
  392.     MOV    R4,A        ;Save sample          1
  393.  
  394. ;Check whether overload is occurring.  F0=1=yes.
  395.     MOV    A,R2        ;MS byte addr         1
  396.     ANL    A,#01111111B    ;Turn LED on          2
  397.     JF0    ON1A        ;Should be on?          2
  398.     ORL    A,#10000000B    ;No, turn off          2
  399.     JMP    OFF1A        ;Continue          2
  400. ON1A    NOP            ;             (1)
  401.     NOP            ;             (1)
  402.     NOP            ;             (1)
  403.     NOP            ;             (1)
  404.  
  405. ;Put sample average into RAM at current address
  406. ;Send address to latches
  407. OFF1A    OUTL    P1,A        ;Out to port 1        2
  408.     ORL    P2,#00000001B    ;LATCH- = 1           2
  409.     MOV    A,R1        ;LS byte addr         1
  410.     OUTL    P1,A        ;Out to port 1        2
  411.  
  412. ;Send data to RAM
  413.     MOV    A,R0        ;Get sample average   1
  414.     OUTL    BUS,A        ;Put onto BUS         2
  415.     ANL    P2,#11011111B    ;WE- = 0              2
  416.     ORL    P2,#00100100B    ;WE-=1, ST-=1         2
  417.  
  418. ;Start the A/D converter
  419.     ANL    P2,#11111011B    ;ST- = 0              2 A/D
  420.     JNI    FAST1B        ;Fast sampling?       2
  421.     CALL    WAIT13        ;No, add 13 states  (13)
  422.  
  423. ;Read the A/D converter into accum
  424. FAST1B    MOVX    A,@R1        ;Dummy to reset BUS   2
  425.     ANL    P2,#11111101B    ;RD- = 0              2
  426.     INS    A,BUS        ;Read A/D data on BUS 2
  427.     ORL    P2,#10000010B    ;RD-=1;CS1-=1         2
  428.  
  429. ;Send accum data to D/A converter
  430.     OUTL    BUS,A        ;Send data to BUS     2
  431.     ANL    P2,#11110111B    ;WR- = 0              2
  432.     ORL    P2,#00001000B    ;WR- = 1              2 D/A
  433.  
  434. ;Check for overload - set F0 if yes.
  435.     CLR    F0        ;LED flag off          1
  436.     JNZ    OFF1B        ;Overload?          2
  437.     CPL    F0        ;Yes!  Turn on         (1)
  438.     JMP    ON1B        ;Continue         (2)
  439. OFF1B    NOP            ;Pad timing          1
  440.     NOP            ;              1
  441.     NOP            ;              1
  442.  
  443. ;Find the average
  444. ON1B    ADD    A,R4        ;Add old value        1
  445.     RRC    A        ;Average the two      1
  446.     MOV    R0,A        ;Save for later       1
  447.  
  448. ;Increment address counters in R2:R1
  449.     MOV    A,R1        ;Get LS byte          1
  450.     ADD    A,#1        ;Bump LS byte         2
  451.     MOV    R1,A        ;Replace              1
  452.     MOV    A,R2        ;Get MS byte          1
  453.     ADDC    A,R7        ;Add carry + (R7=0)   1
  454.     MOV    R2,A        ;Replace              1
  455.     JB7    TEST1        ;Change RAM?          2
  456.     JF1    MAN2A        ;Manual, stop rec.
  457.     JMP    TEST0        ;Yes
  458.  
  459. TEST1    JT1    TC        ;T1 up?  Check T0     2
  460.     MOV    A,R2        ;No, fix start addr
  461.     XRL    A,#10000000B    ;Addr 5 secs back
  462.     MOV    R7,A        ;Save as MS start
  463.     JMP    PL1        ;Now play
  464.  
  465. TC    JT0    REC1        ;T0 up?  Keep rec.    2
  466.  
  467.     MOV    A,R2        ;Addr 10 secs back
  468.     MOV    R7,A        ;Save as MS start
  469.  
  470. PL1    MOV    A,R1        ;LS byte addr
  471.     MOV    R6,A        ;Save LS start/end
  472.     MOV    A,R2        ;Get MS addr end
  473.     MOV    R5,A        ;Save as MS end
  474.  
  475. ;Set starting address for playing
  476. START1    MOV    A,R7        ;Get MS start
  477.     MOV    R2,A        ;Into counter
  478.     MOV    A,R6        ;Get LS start
  479.     MOV    R1,A        ;Into counter
  480.  
  481. ;------------------- PLAY --------------------------
  482. ;Get a byte from current address into accum
  483. ;Send address to latches
  484. PLAY1    MOVX    A,@R1        ;Dummy to reset BUS   2
  485.     ANL    P2,#01111111B    ;CS1- = 0             2
  486.     MOV    A,R2        ;MS byte addr         1
  487.     ORL    A,#10000000B    ;Turn off LED          2
  488.     OUTL    P1,A        ;Out to port 1        2
  489.     ANL    P2,#11111110B    ;LATCH- = 0           2
  490.     ORL    P2,#00000001B    ;LATCH- = 1           2
  491.     MOV    A,R1        ;LS byte addr         1
  492.     OUTL    P1,A        ;Out to port 1        2
  493.     ANL    P2,#11101111B    ;OE- = 0              2
  494.     INS    A,BUS        ;Read RAM data on BUS 2
  495.     ORL    P2,#00010000B    ;OE- = 1              2
  496.     ORL    P2,#10000000B    ;CS1- = 1             2
  497.  
  498. ;Find the average
  499.     MOV    R3,A        ;Save sample for now  1
  500.     ADD    A,R4        ;R4 = old sample      1
  501.     RRC    A        ;Find average         1
  502.     NOP            ;Pad timing          1
  503.     NOP            ;              1
  504.     NOP            ;              1
  505.     NOP            ;              1
  506.     NOP            ;              1
  507.  
  508. ;Send accum data to D/A converter
  509.     JNI    FAST1C        ;Fast sampling?       2
  510.     CALL    WAIT13        ;No, add 13 states  (13)
  511. FAST1C    OUTL    BUS,A        ;Send data to BUS     2
  512.     ANL    P2,#11110111B    ;WR- = 0              2
  513.     ORL    P2,#00001000B    ;WR- = 1              2 D/A
  514.  
  515. ;Increment address counters in R2:R1
  516.     MOV    A,R1        ;Get LS byte          1
  517.     ADD    A,#1        ;Bump LS byte         2
  518.     MOV    R1,A        ;Replace              1
  519.     MOV    A,R2        ;Get MS byte          1
  520.     ADDC    A,#0        ;Add carry            2
  521.     MOV    R2,A        ;Replace              1
  522.     JB7    TE        ;Change RAM?          2
  523.     JF1    MAN2A        ;Manual, stop play
  524.     JMP    TST0        ;Yes
  525.  
  526. TE    MOV    A,R1        ;Get LS addr          1
  527.     XRL    A,R6        ;At end?              1
  528.     JNZ    TST1        ;Not yet              2
  529.  
  530.     MOV    A,R2        ;Get MS addr          1
  531.     XRL    A,R5        ;At end?              1
  532.     JZ    START1        ;Yes, restart         2
  533.  
  534. TST1    JT1    TD        ;T1 up?               2
  535.     JMP    PLAY1A        ;No, play sound       2
  536.  
  537. TD    JT0    REC1X        ;Finished playing?
  538.  
  539. PLAY1A    MOV    A,R3        ;Recall new sample    1
  540.     MOV    R4,A        ;Make into old        1
  541.     CALL    WAIT13        ;Wait 13 states         13
  542.     NOP            ;Pad timing          1
  543.  
  544. ;Send sample to D/A converter
  545.     JNI    FAST1D        ;Fast sampling?       2
  546.     CALL    WAIT13        ;No, add 13 states  (13)
  547. FAST1D    OUTL    BUS,A        ;Send data to BUS     2
  548.     ANL    P2,#11110111B    ;WR- = 0              2
  549.     ORL    P2,#00001000B    ;WR- = 1              2 D/A
  550.     JMP    PLAY1        ;Keep playing         2
  551.  
  552. MAN2A    JMP    MAN2        ;Cross page jumps
  553.  
  554. ;--------------------------------------------------------
  555. ;------------------- Memory Page 2 ----------------------
  556. ;--------------------------------------------------------
  557.     ORG    0200H
  558.  
  559. ;---------------------------------------------------
  560. INIT    ;Initialize ports, BUS, and memories
  561.     SEL    RB0        ;Use RAM register bank 0
  562.     SEL    MB0        ;...and EPROM mem bank 0
  563.     MOV    A,#11111111B    ;All ones
  564.     OUTL    P1,A        ;Port 1 = 11111111B
  565.     OUTL    BUS,A        ;BUS    = 11111111B
  566.     MOV    A,#11111011B    ;ST- idles low
  567.     OUTL    P2,A        ;Port 2 = 11111011B
  568.     MOV    R7,#0        ;MS start addr
  569.     MOV    R6,#0        ;LS start addr
  570.     MOV    R5,#0        ;MS end addr
  571.     MOV    R4,#0        ;Temp sample storage
  572.     MOV    R3,#0        ;Temp sample storage
  573.     MOV    R2,#0        ;MS curr addr
  574.     MOV    R1,#0        ;LS curr addr
  575.     MOV    R0,#127        ;sample average
  576.     CLR    F0        ;Overload LED off
  577.     CLR    F1        ;Automatic mode
  578.     RETR
  579.  
  580. ;---------------------------------------------------
  581. CLEAR    ;Clear RAM memory, two bytes at a time
  582.     MOV    A,#127        ;"zero" sample voltage
  583.     OUTL    BUS,A        ;Send to BUS/RAM
  584.     MOV    R2,#00000000B    ;MS address = 0; LED on
  585.     MOV    R1,#00000000B    ;LS address = 0
  586.     ANL    P2,#00111111B    ;CS0-,CS1-=0
  587.  
  588. MORCLR    MOV    A,R2        ;MS address
  589.     OUTL    P1,A        ;To latch
  590.     ANL    P2,#11111110B    ;LATCH-=0
  591.     ORL    P2,#00000001B    ;LATCH-=1
  592.     MOV    A,R1        ;LS address
  593.     OUTL    P1,A        ;To port 1
  594.     ANL    P2,#11011111B    ;WE-=0
  595.     ORL    P2,#00100000B    ;WE-=1        
  596.  
  597.     MOV    A,R1        ;LS address
  598.     ADD    A,#1        ;Bump address
  599.     MOV    R1,A        ;Replace
  600.     MOV    A,R2        ;MS address
  601.     ADDC    A,#0        ;Add carry
  602.     MOV    R2,A        ;Replace
  603.     JB7    NOCLR        ;More than 32k ?
  604.     JMP    MORCLR        ;Continue
  605.  
  606. NOCLR    ORL    P2,#11000000B    ;CS0-,CS1-=1        
  607.     RETR            ;Finished
  608.  
  609. ;---------------------------------------------------
  610. MANUAL    ;Manual record/play mode requested
  611.     CALL    CLEAR        ;Clear all of RAM memory
  612. MAN3    JNT0    MAN3        ;Wait for key up
  613.     CALL    DEBOUN        ;Debounce key
  614.     CALL    LEDON        ;Turn on LED
  615.  
  616. ;Get a sample and output to DAC
  617. WAIT1    CALL    SAMPLE        ;A/D and D/A
  618.     JNT1    CANCEL        ;Press T1 to cancel
  619.     JT0    WAIT1        ;T0 up, wait
  620.  
  621.     CALL    LEDOFF        ;Turn off LED
  622.     CLR    F1        ;Ready to set F1
  623.     CPL    F1        ;F1=1, LED is off
  624.     JMP    RECMAN        ;Record from start
  625.  
  626. MAN2    ;Back from recording or playing 64k
  627.     CALL    LEDON        ;Turn on LED
  628.  
  629. ;Get a sample and output to DAC
  630. WAIT2    CALL    SAMPLE        ;A/D and D/A
  631.     JNT1    CANCEL        ;Press T1 to cancel
  632.     JT0    WAIT2        ;Wait for T0 press
  633.  
  634.     JMP    PLAY0        ;Now play 64k
  635.  
  636. CANCEL    ;T1 was pressed while in Memory Idle modes.
  637.     ;Cancel Memory mode.
  638.     CALL    INIT        ;Initialize & clear flag
  639.     CALL    LEDOFF        ;Turn off LED
  640.     JMP    REC0X        ;"Warm" reboot
  641.  
  642. ;---------------------------------------------------
  643. SAMPLE    ;Do A/D and D/A conversion
  644.     ORL    P2,#00000100B    ;ST- = 1
  645.     ANL    P2,#11111011B    ;ST- = 0
  646.     MOVX    A,@R1        ;Dummy to reset BUS
  647.     ANL    P2,#11111101B    ;RD- = 0
  648.     INS    A,BUS        ;Read A/D on BUS
  649.     ORL    P2,#00000010B    ;RD- = 1
  650.     OUTL    BUS,A        ;Send data to BUS
  651.     ANL    P2,#11110111B    ;WR- = 0
  652.     ORL    P2,#00001000B    ;WR- = 1
  653.     RETR
  654.  
  655. ;---------------------------------------------------
  656. LEDON    ;Turn on LED
  657.     ANL    A,#01111111B    ;Turn on LED
  658.     OUTL    P1,A        ;Out to port 1
  659.     ANL    P2,#11111110B    ;LATCH- = 0
  660.     ORL    P2,#00000001B    ;LATCH- = 1
  661.     RETR
  662.  
  663. ;---------------------------------------------------
  664. LEDOFF    ;Turn off LED
  665.     ORL    A,#10000000B    ;Turn off LED
  666.     OUTL    P1,A        ;Out to port 1
  667.     ANL    P2,#11111110B    ;LATCH- = 0
  668.     ORL    P2,#00000001B    ;LATCH- = 1
  669.     RETR
  670.  
  671. ;---------------------------------------------------
  672. DEBOUN    ;Wait 50 milliseconds
  673.     CALL    MS10        ;Wait 10 ms.
  674.     CALL    MS10        ;Wait 10 ms.
  675.     CALL    MS10        ;Wait 10 ms.
  676.     CALL    MS10        ;Wait 10 ms.
  677.     CALL    MS10        ;Wait 10 ms.
  678.     RETR
  679.  
  680. ;---------------------------------------------------
  681. MS10    ;Use timer to time 10 ms., approximately.
  682.     ;Timer counts at a rate of xtal/15/32 Hz
  683.     ;= 23.04 kHz (43.4028 us/count).
  684.     MOV    A,#26        ;230 counts
  685.     MOV    T,A        ;Into timer
  686.     STRT    T        ;Start timer
  687. NOTFIN    JTF    TIMFIN        ;Finished
  688.     JMP    NOTFIN
  689. TIMFIN    RETR
  690.  
  691. ;---------------------------------------------------
  692. WAIT13    ;Wait 13 states including CALL and RETR
  693.     NOP
  694.     NOP
  695.     NOP
  696.     NOP
  697.     NOP
  698.     NOP
  699.     NOP
  700.     NOP
  701.     NOP
  702.     RETR
  703.  
  704. ;--------------------------------------------------------
  705. ;------------------- Memory Page 3 ----------------------
  706. ;--------------------------------------------------------
  707.  
  708. ;--------------------------------------------------------
  709.     ORG    03B0H
  710.  
  711. NOTICE    ;Copyright notice takes from 03B0H to 03FEH
  712.  
  713.     DB    ' (c) copyright 1993,'
  714.     DB    ' Reyer & Associates,'
  715.     DB    ' WA9VNJ QSOcorder'
  716.     DB    ' version 2.3'
  717.     DB    ' 10/17/93'
  718.     DB    ' '
  719.  
  720.     END
  721.